
/********************************************************
Ejemplo para el archivo CFG:

driver(
size [640 480]
)
*********************************************************/

#include "streamcamera.h"
#include "stdio.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h> 
#include <unistd.h>




//Funcion para retornar el driver
Driver* 
StreamCamera_Init(ConfigFile* cf, int section)
{
  // Create and return a new instance of this driver
  return((Driver*)(new StreamCamera(cf, section)));
}


// A driver registration function, again declared outside of the class so
// that it can be invoked without object context.  In this function, we add
// the driver into the given driver table, indicating which interface the
// driver can support and how to create a driver instance.
void StreamCamera_Register(DriverTable* table)
{
  table->AddDriver("StreamCamera", StreamCamera_Init);
}


// Constructor of class StreamCamera
StreamCamera::StreamCamera(ConfigFile* cf, int section)
    : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, PLAYER_CAMERA_CODE)
{
	//First read data regarding connection to streaming server
	this->conn.ipAddr = cf->ReadString(section,"ipaddr",DEFAULT_IPADDR);
	this->conn.port = cf->ReadInt(section,"port",DEFAULT_PORT);
	this->conn.action = cf->ReadString(section,"action",DEFAULT_ACTION);

	//Read url for file
	this->fileUrl = cf->ReadString(section,"file_url",DEFAULT_FILE_URL);
	
	//define debuggin for cURL
	this->curlDebug = cf->ReadInt(section,"curl_debug",0);
	
	//Then read size of image
	this->width = cf->ReadTupleInt(section, "size", 0, 640);
  this->height = cf->ReadTupleInt(section, "size", 1, 480);
  printf("StreamCamera: Cam width: %d height: %d\n",this->width,this->height);
}


int StreamCamera::Setup()
{
	printf("StreamCamera: Driver initializing\n");

	//allocate memory for http direction
	this->conn.http_dir = new char[255];
	
	sprintf(this->conn.http_dir,"%s:%d/?action=%s",this->conn.ipAddr,this->conn.port, this->conn.action);
	printf("StreamCamera: Streaming server: %s\n",this->conn.http_dir);
		
	//cURL init
	curlConn = curl_easy_init();
	
	this->StartThread();
  printf("StreamCamera: Driver initialization done\n");
  return(0);
}


// Shutdown the device
int StreamCamera::Shutdown()
{
	printf("StreamCamera: Driver shutting down\n");
	
	//stop cURL
	if(curlConn)
		curl_easy_cleanup(curlConn);
	// Stop and join the driver thread
  StopThread();
 
  printf("StreamCamera: Driver has been shutdown\n"); 
  
  delete this->conn.http_dir;
  
  return 0;
}

int StreamCamera::ProcessMessage(MessageQueue* resp_queue, 
                                  player_msghdr * hdr,
                                  void * data)
{
	//nothing to do for now
	return -1;
}

// Main function for device thread
void StreamCamera::Main() 
{
	bool firstTime = false;
  // The main loop; interact with the device here
  for(;;)
  {
    // test if we are supposed to cancel
    pthread_testcancel();

    // Process incoming messages. In this  case, no messages are processed.
    ProcessMessages();

		if(!firstTime)
			RefreshData();
			
		//firstTime = true;
			
    // Sleep (you might, for example, block on a read() instead)
    //usleep(100000);
  }
}



void StreamCamera::RefreshData()
{

	static int i = 0;
	char name[] = "img";
	char nombre[255];
	
	sprintf(nombre,"%s%d.jpg",name,i++);
	
	if(curlConn)
		fp = fopen(fileUrl, "wb");
		{
		curl_easy_setopt(curlConn, CURLOPT_WRITEFUNCTION, NULL);
		curl_easy_setopt(curlConn, CURLOPT_VERBOSE,curlDebug);
		curl_easy_setopt(curlConn, CURLOPT_URL, this->conn.http_dir);
		curl_easy_setopt(curlConn, CURLOPT_WRITEDATA, fp);

		// Grab image
		curlResult = curl_easy_perform(curlConn);
		
		fclose(fp);
		if(curlResult){
			printf("StreamCamera: Cannot grab the image!\n");
			
			return;
		}
	}

	struct stat fileStats;
	
	stat(fileUrl,&fileStats);
	
	fp = fopen(fileUrl, "r");
	
  size_t size;
  // Store image details
  this->data.width = this->width; 
  this->data.height = this->height; 
  this->data.bpp = 24; 
  this->data.format = PLAYER_CAMERA_FORMAT_RGB888;
  this->data.fdiv = 1; 
  this->data.compression = PLAYER_CAMERA_COMPRESS_JPEG;
  this->data.image_count = fileStats.st_size ;
  
  fread(this->data.image, 1, this->data.image_count, fp); 
  fclose(fp); 

  // Work out the data size; do this BEFORE byteswapping
  size = sizeof(this->data) - sizeof(this->data.image) + this->data.image_count;
  
  // Write data to the client (through the server)
  Publish (device_addr, NULL, PLAYER_MSGTYPE_DATA, PLAYER_CAMERA_DATA_STATE, &data, size,NULL);
  
  
  return;
}


////////////////////////////////////////////////////////////////////////////////
// Extra stuff for building a shared object.

/* need the extern to avoid C++ name-mangling  */
extern "C" {
  int player_driver_init(DriverTable* table)
  {
    puts("StreamCamera: driver initializing");
    StreamCamera_Register(table);
    puts("StreamCamera: driver done");
    return(0);
  }
}
